package com.third.device.mg.serialport.factory.forick

import com.third.device.mg.serialport.utils.SLog
import com.third.device.mg.serialport.utils.to2ByteL
import com.third.device.mg.serialport.utils.toHexString

/**
 * company 广东玛格家居有限公司
 * @author smoker
 * @Date 2021/12/22
 * Description:弗雷克的产品
 *
 * 指令特点：数据的高8位放在指令前 ，数据的低8位放在指令后
 * 例如：
 * int num = 4660
 * num ==>> 16进制为 0x1234
 * num ==>> byte[]数组为: [32 ,12] ==>>计算器一般为小端模式 ，低位在前，高位在后，所以将12放在32的前面
 */
abstract class BaseForickProduct {

    companion object {
        private const val TAG = "Forick_Command:"

        //功能模式 -- 1 byte
        const val READ_MODE = 0x03.toByte() //读取寄存器
        const val WRITE_SINGLE_MODE = 0x06.toByte()//设置单个寄存器
        const val WRITE_MULTI_MODE = 0x10.toByte() //设置多个寄存器
    }



    /**
     * 创建单写入指令
     */
    fun createSingleWriteCommand(address: Byte,hlr: ByteArray):ByteArray{
        val pushMsg = ByteArray(6)
        pushMsg[0] = address
        pushMsg[1] = WRITE_SINGLE_MODE
        System.arraycopy(hlr, 0, pushMsg, 2, hlr.size)
        return  pushMsg
    }

    /**
     * 创建单读取指令
     */
    fun createSingleReadCommand(address: Byte,hlr: ByteArray):ByteArray{
        val pushMsg = ByteArray(6)
        pushMsg[0] = address
        pushMsg[1] = READ_MODE
        System.arraycopy(hlr, 0, pushMsg, 2, hlr.size)
        return  pushMsg
    }

    /**
     * 弗雷克最后2个字节 校验
     */
    fun crcCheck(pushMsg: ByteArray): ByteArray {
        //校验码
        val code = ForickCRC.crc16LowBefore(pushMsg)
        //校验码转成2个字节
        val crcBytes = code.to2ByteL()
        val command = ByteArray(pushMsg.size + crcBytes.size)
        System.arraycopy(pushMsg, 0, command, 0, pushMsg.size)
        /*数据的 高位放在指令前 ，低位放在指令后*/
        command[command.size - 2] = crcBytes[1]
        command[command.size - 1] = crcBytes[0]
        SLog.d(TAG ,command.toHexString())
        return command
    }


    /**
     * 产品描述
     */
    abstract fun productDescribe(): String


}